package com.google.gwt.mobile.widgets.ui;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.mobile.widgets.event.TouchController;
import com.google.gwt.mobile.widgets.event.SwipeEvent;
import com.google.gwt.mobile.widgets.event.SwipeEventHandler;
import com.google.gwt.mobile.widgets.transition.Transition;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

/**
 * The Class SlidePanel.
 */
public class SlidePanel extends TransitionWidget implements HasWidgets, SwipeEventHandler {

  /**
   * The Interface SlideProvider.
   */
  public interface SlideProvider {
    Slide loadSlide(int index);
  }

  protected FlowPanel _panel = new FlowPanel();
  protected int _count = 0;
  protected int _current = 0;
  protected SlideProvider _slideProvider = null;
  protected ArrayList<Widget> _slides = new ArrayList<Widget>();

  /**
   * Instantiates a new slide panel.
   */
  public SlidePanel() {
    initWidget(_panel);
    setStyleName("SlidePanel");
  }

  /**
   * Sets the slide count.
   * 
   * @param count the new slide count
   */
  public void setSlideCount(final int count) {
    _count = count;
  }

  /**
   * Gets the slide count.
   * 
   * @return the slide count
   */
  public int getSlideCount() {
    return _count > 0 ? _count : _slides.size();
  }

  /**
   * Sets the slide provider.
   * 
   * @param provider the new slide provider
   */
  public void setSlideProvider(final SlideProvider provider) {
    _slideProvider = provider;
  }

  /**
   * Gets the slide provider.
   * 
   * @return the slide provider
   */
  public SlideProvider getSlideProvider() {
    return _slideProvider;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.TransitionalComposite#onInitialLoad()
   */
  @Override
  public void onInitialLoad() {
    super.onInitialLoad();
    _current = 0;
    Slide slide = getSlide(_current);
    if (slide != null) {
      _panel.add(slide);
    }
  }

  /**
   * Gets the slide.
   * 
   * @param index the index
   * @return the slide
   */
  public Slide getSlide(final int index) {
    Slide slide = null;
    if (_slideProvider != null) {
      slide = _slideProvider.loadSlide(index);
    }
    if (slide == null && index < _slides.size()) {
      slide = (Slide) _slides.get(index);
    }
    return slide;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.google.gwt.user.client.ui.Widget#onLoad()
   */
  @Override
  public void onLoad() {
    super.onLoad();
    TouchController.get().addSwipeEventHandler(this);
  }

  @Override
  protected void onUnload() {
    TouchController.get().removeSwipeEventHandler(this);
    super.onUnload();
  }

  /**
   * Next.
   */
  public void next() {
    if (_current >= getSlideCount() - 1) {
      return;
    }
    _current++;
    Slide to = getSlide(_current);
    Slide from = (Slide) _panel.getWidget(0);
    Transition transition = Transition.SLIDE;
    transition.start(from, to, _panel, false);
  }

  /**
   * Previous.
   */
  public void previous() {
    if (_current <= 0) {
      return;
    }
    _current--;
    Slide to = getSlide(_current);
    Slide from = (Slide) _panel.getWidget(0);
    Transition transition = Transition.SLIDE;
    transition.start(from, to, _panel, true);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.TransitionalComposite#onTransitionEnd()
   */
  @Override
  public void onTransitionEnd() {
    super.onTransitionEnd();
    _panel.remove(0);
  }

  /**
   * Gets the current slide index.
   * 
   * @return the current slide index
   */
  public int getCurrentSlideIndex() {
    return _current;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.user.client.ui.HasWidgets#add(com.google.gwt.user.client
   * .ui.Widget)
   */
  @Override
  public void add(final Widget w) {
    _slides.add(w);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.google.gwt.user.client.ui.HasWidgets#clear()
   */
  @Override
  public void clear() {
    _slides.clear();

  }

  /*
   * (non-Javadoc)
   * 
   * @see com.google.gwt.user.client.ui.HasWidgets#iterator()
   */
  @Override
  public Iterator<Widget> iterator() {
    return _slides.iterator();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.user.client.ui.HasWidgets#remove(com.google.gwt.user.client
   * .ui.Widget)
   */
  @Override
  public boolean remove(final Widget w) {
    return _slides.remove(w);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.event.SwipeEventHandler#onSwipeUp(
   * com.google.gwt.mobile.widgets.event.SwipeEvent)
   */
  @Override
  public void onSwipeUp(final SwipeEvent e) {
    // noop
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.event.SwipeEventHandler#onSwipeDown
   * (com.google.gwt.mobile.widgets.event.SwipeEvent)
   */
  @Override
  public void onSwipeDown(final SwipeEvent e) {
    // noop

  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.event.SwipeEventHandler#onSwipeLeft
   * (com.google.gwt.mobile.widgets.event.SwipeEvent)
   */
  @Override
  public void onSwipeLeft(final SwipeEvent e) {
    next();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * com.google.gwt.mobile.widgets.event.SwipeEventHandler#onSwipeRight
   * (com.google.gwt.mobile.widgets.event.SwipeEvent)
   */
  @Override
  public void onSwipeRight(final SwipeEvent e) {
    previous();
  }
}
